package com.kyg.tjtoolmanager.net.netty.manager;


import com.alibaba.fastjson.JSON;
import com.kyg.tjtoolmanager.App;
import com.kyg.tjtoolmanager.db.SQLiteUtils;
import com.kyg.tjtoolmanager.net.netty.factory.ChannelFactory;
import com.kyg.tjtoolmanager.net.netty.factory.HttpResponseFactory;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.util.internal.StringUtil;

import java.util.Map;
import java.util.Objects;

public class HttpKeepAliveManager {


    private static final int KEEP_ALIVE_CONNECTION_TIME_OUT = 10000;

    /**
     * 通过长连接获取返回结果
     *
     * @param serialNo    序列号
     * @param httpRequest 请求类
     * @return
     * @throws InterruptedException
     */
    public synchronized static Map<String, String> getResponseMapByKeepAliveConnection(String serialNo, FullHttpRequest httpRequest) throws InterruptedException {
        Map responseMap = null;
        Integer responseKey = null;
        try {
            //通过设备编码获取，通道
            ChannelHandlerContext ctx = null;
            DeviceChannelContext deviceChannelContext = ChannelFactory.getChannelBySerialNo(serialNo);
            if (Objects.nonNull(deviceChannelContext)) {
                ctx = deviceChannelContext.getCtx();
            }
            if (Objects.isNull(ctx)) {
//                SQLiteUtils.insertLog("未找到设备:{" + serialNo + "}的连接信息");
                return null;
            } else {
                ChannelFactory.unLockByDeviceCode(serialNo);
            }
            //发起请求前，先做移除
            responseKey = ctx.hashCode();
            HttpResponseFactory.RESPONSE_DATA.remove(responseKey);
            String response = "";
            if (ctx != null && ctx.channel().isWritable()) {
                ctx.writeAndFlush(httpRequest);
                //处理成 responseMap
                response = HttpResponseFactory.getResponse(ctx, KEEP_ALIVE_CONNECTION_TIME_OUT);
            } else {
                SQLiteUtils.insertLog("[DEVICE_CODE = {" + serialNo + "}]...... netty queue is line up, return fail ......");
                ctx.channel().close();
                deviceChannelContext.setCtx(null);
            }
            if (!StringUtil.isNullOrEmpty(response)) {
                response.replace("\"Data\": \n" +
                        "\t}", "\"Data\":{}");
                responseMap = JSON.parseObject(response, Map.class);
            }
        } catch (Exception e) {
            SQLiteUtils.insertLog(e.getMessage());
            //异常移除链接
            ChannelFactory.removeChannelByDeviceCode(serialNo);
            ChannelFactory.unLockByDeviceCode(serialNo);
        } finally {
            if (Objects.nonNull(responseKey)) {
                //移除数据 无论是否取到，做移除
                HttpResponseFactory.RESPONSE_DATA.remove(responseKey);
                ChannelFactory.unLockByDeviceCode(serialNo);
            }
        }
        return responseMap;
    }
}
